AWS SAMでAWS Lambda関数にAmazon EventBridge Schedulerを設定すると、暗黙的に関連リソースも追加されたので調べてみた
Amazon EventBridge Schedulerの他にもリソースが追加されている?
おのやんです。
みなさん、AWS SAM(以下、SAM)でAWS Lambda(以下、Lambda)を定期実行するAmazon EventBridge (以下、EventBridge) Schedulerを追加した時に、EventBridge Scheduler以外のリソースが追加されてることを不思議に思ったことはありませんか?私はあります。
SAMはAWS CloudFormation(以下、CFn)の拡張であるため、CFnと違ってテンプレートに明示的に記述した以外のリソースも暗黙的に作成してくれます。そのためCFnに慣れた方の中には「このリソース、記述してないけど作成対象に入ってるんだが?」と疑問に思う方もいます。
ということで、今回はLambda関数にEventBridge Schedulerを追加した時に暗黙的に作成されるリソースをまとめてみたいと思います。
公式情報
ドキュメントを確認してみると、SAMのLambda関数のEvents
に設定するEventBridgeRule
の詳細には、「AWS::Lambda::Permission
も追加される」と明記してあります。
EventBridgeRule
EventBridgeRule
イベントソースタイプを記述するオブジェクト。サーバーレス関数を Amazon EventBridge ルールのターゲットとして設定します。詳細については、「Amazon ユーザーガイド」の「Amazon とは EventBridge」を参照してください。 EventBridgeAWS SAM が を生成する AWS::Events::Rule このイベントタイプが設定されている場合の リソース。 AWS SAM は
AWS::Lambda::Permission
リソースも作成します。 これは、 が Lambda を呼びEventBridgeRule
出すために必要です。
またEventBridgeRule
の他にも、Eventsに設定する項目によっては、他のリソースを暗黙的に作成するとのことです。
EventSource
関数をトリガーするイベントのソースを説明するオブジェクトです。各イベントは、1 つのタイプ と、そのタイプに依存する一連のプロパティ で構成されます。各イベントソースのプロパティの詳細については、そのタイプに対応するトピックを参照してください。
検証
まずは、簡単なSAMテンプレートを用いてLambda関数を作成してみます。こちらは、sam init
を実行した時に最初に作成されるLambda関数を元に、Lambda部分のみ残したSAM テンプレートです。
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
aws-test-sample-app
Sample SAM Template for aws-test-sample-app
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
MemorySize: 128
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
こちらのテンプレートを、sam build
、sam deploy
コマンドでデプロイします。
そして次に、こちらのテンプレートにEventBridge Schedulerを追加します。
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
aws-test-sample-app
Sample SAM Template for aws-test-sample-app
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
MemorySize: 128
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
+ Events:
+ PeriodicSchedule:
+ Type: Schedule
+ Properties:
+ Enabled: true
+ Schedule: !Sub "cron(*/15 * * * ? *)"
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
この状態でsam build
、sam deploy
を実行して、前回デプロイ時とのリソースの差分を確認します。
EventBridege Scheduler 追加時に作成されるリソース
上記の状態で差分を確認してみると、以下の出力確認できます。これより、SAM経由でLambda関数にEventBridge Schedulerを追加した際に、AWS::Lambda::Permission
リソースも作成されます。
...
Waiting for changeset to be created..
CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add HelloWorldFunctionPeriodicSchedulePermissio AWS::Lambda::Permission N/A
n
+ Add HelloWorldFunctionPeriodicSchedule AWS::Events::Rule N/A
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
...
追加されるリソースの命名は、出力を確認する限りだと以下のようになっています
- EventBridgeルール(EventBridge Scheduler)名
<Lambda関数名>PeriodicSchedule
- Lambdaに付与されるリソースベースポリシー
<Lambda関数名>PeriodicSchedulePermission
EventBridgeのルールは、SAMテンプレートに記述したようにそのまま設定されています。
デプロイ後は、こちらのようにLambda関数にリソースベースのポリシーステートメントが追加されていることがわかります。これにより、Lambda関数を実行する権限をEventBridgeルールに付与しています。
ポリシーステートメントの内容は以下の通りです。
項目 | 値 |
---|---|
Statement ID | aws-test-sample-app-HelloWorldFunctionPeriodicSchedulePermission-<uuid> |
Principal | events.amazonaws.com |
Effect | Allow |
Action | lambda:InvokeFunction |
Conditions | 以下のJSON |
{
"ArnLike": {
"AWS:SourceArn": "arn:aws:events:ap-northeast-1:<accound_id>:rule/aws-test-sample-app-HelloWorldFunctionPeriodicSched-abcdefghijkl"
}
}
Events
の項目を設定すると、関連リソースも作成されることがある
SAMテンプレートで今回の検証項目はEventBridge Schedulerでしたが、例えばDynamoDBイベントを設定するとAWS::Lambda::EventSourceMapping
リソースを作成するなど、イベントによって作成する関連リソースが異なる点にも注意したいですね。
この仕様は知らないと結構戸惑うと思うので、これを機に意識していただければと思います。では!